package com.yzwu.optional;

/**
 * @author yzwu
 * @date 2022/5/28 7:41 PM
 */

import com.yzwu.lambda.Employee;
import org.junit.Test;

import java.util.Optional;

/**
 * 定义：Optional 类 (java.util.Optional) 是一个容器类，
 * 代表一个值存在或不存在，原来用 null 表示一个值不存在，现在用 Optional 可以更好的表达这个概念；并且可以避免空指针异常
 * <p>
 * 常用方法：
 * <p>
 * Optional.of(T t)：创建一个 Optional 实例
 * Optional.empty(T t)：创建一个空的 Optional 实例
 * Optional.ofNullable(T t)：若 t 不为 null，创建 Optional 实例，否则空实例
 * --------------------------------------------下面才是常用！
 * isPresent()：判断是否包含某值
 * orElse(T t)：如果调用对象包含值，返回该值，否则返回 t
 * orElseGet(Supplier s)：如果调用对象包含值，返回该值，否则返回 s 获取的值
 * map(Function f)：如果有值对其处理，并返回处理后的 Optional，否则返回 Optional.empty()
 * flatmap(Function mapper)：与 map 相似，要求返回值必须是 Optional
 * <p>
 * Optional.of(T t)：
 */
public class OptionalAPI {
    @Test
    public void test01() {
        Optional<Employee> employee = Optional.of(new Employee());
        System.out.println(employee.get());

        System.out.println("==========");

        Optional<Object> o = Optional.of(null);
        System.out.println(o.get());
    }

    @Test
    public void test02() {
        Optional<Object> empty = Optional.empty();
        System.out.println(empty.get());
    }

    @Test
    public void test03() {
        Optional<Employee> employee = Optional.ofNullable(null);
        if (employee.isPresent()) {
            System.out.println(employee.get());
        }
        //避免空指针异常
        Employee emp = employee.orElse(new Employee(888, "jackkk", 123, 23456.78));
        System.out.println(emp);
        //可以传递一些功能
        System.out.println(employee.orElseGet(() -> new Employee()));
    }
    @Test
    public void test04(){
        Man man = new Man();
        String goddessName = getGoddessName(man);
        System.out.println(goddessName);
    }

    /**
     * 获取一个男人心中的女神的名字
     * @param man
     * @return
     */
    public String getGoddessName(Man man){
//        return man.getGoddess().getName();//空指针异常java.lang.NullPointerException
        /// 判空，防止空指针
        if (man != null){
            Goddess goddess = man.getGoddess();
            if (goddess != null){
                return goddess.getName();
            }
        }
        return "苍老师";
    }
    //  那如果一层套一层，男人心中有女神，女神心中有她的男神，男神又有他的女神…此时如果再用 if 判空就很麻烦了

    @Test
    public void test05(){
        Optional<Goddess> goddess = Optional.ofNullable(new Goddess("深田"));
        Optional<NewMan> newMan = Optional.ofNullable(new NewMan(goddess));
        String name1 = getGoddessName2(newMan);
        System.out.println(name1);

        System.out.println("==========");

        Optional<NewMan> optional = Optional.ofNullable(null);
        String name2 = getGoddessName2(optional);
        System.out.println(name2);
    }

    //精髓就是把可能为null的变成Optional<NewMan>类型，就可以orelse了
    public String getGoddessName2(Optional<NewMan> newMan){
        return newMan.orElse(new NewMan())
                .getGoddess()
                .orElse(new Goddess("三上悠亚"))
                .getName();
    }


}
